<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>

    <link rel="stylesheet" type="text/css" 
      href="/assets/css/straybirds.css" media="screen" />
    <link rel="stylesheet" type="text/css" 
      href="/assets/css/pygments.css" media="screen" />

    <!-- MathJax Section Start -->

    <script type="text/javascript"
    src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
    </script>
    <script>
        MathJax.Hub.Config({
              tex2jax: {
              skipTags: ['script', 'noscript', 'style', 'textarea', 'pre']
              }
        });
        MathJax.Hub.Queue(function() {
            var all = MathJax.Hub.getAllJax(), i;
            for(i=0; i < all.length; i += 1) {
                all[i].SourceElement().parentNode.className += ' has-jax';
            }
        });
    </script>

    <!-- MathJax Section End -->

    <!-- Google Analytics Start-->
    <script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-48100787-1', 'minixalpha.github.io');
  ga('send', 'pageview');

</script>

    <!-- Google Analytics End -->

    <title>首页</title>
  </head>

  <body>
    <div class="container">
      <header>
        <div class="container">
          <h1>
              <a href="/" title="Home Page"> 潇湘夜雨 </a>
          <span class="github-src">
            <a href ="https://github.com/minixalpha/minixalpha.github.io"
               target="_blank"
               title="Fork me on GitHub">
              <img src="/assets/images/GitHub-Mark-Light-32px.png" alt="">
            </a>
          </span>
          </h1>
        </div>
      </header>

      <aside id="left-side">
        <h2> 分类 </h2>
  <ul class="category-list">
      
            
                <li>
                <a href="/categories/计算机系统"> 计算机系统 (3) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/java"> java (1) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/技术"> 技术 (5) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/工具"> 工具 (4) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/科研"> 科研 (5) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/生活"> 生活 (1) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/思想"> 思想 (2) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/c语言"> c语言 (4) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/虚拟机"> 虚拟机 (1) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/英语"> 英语 (8) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/读书"> 读书 (1) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/源代码阅读"> 源代码阅读 (10) </a>
                </li>
            
      
  </ul>

      </aside>

      <aside id="right-side">
        <h2> 归档 </h2>
  <ul class="archive-list">
    
    
    
        
        
        
        
            
            <li>
                <a href="/2014/05">
                    2014-05 (1)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2014/04">
                    2014-04 (3)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2014/03">
                    2014-03 (11)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2014/02">
                    2014-02 (6)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2014/01">
                    2014-01 (3)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2013/11">
                    2013-11 (10)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2013/10">
                    2013-10 (3)
                </a>
            </li>

        
        
    
  </ul>

      </aside>

      <article>

<ul class="post-list">
    
    <li>
      <div class="post-title">
        <a href="/%E5%B7%A5%E5%85%B7/2014/02/15/github-jekyll-markdown.html"> 使用 GitHub, Jekyll, Markdown 打造自己的博客</a> </br>
      </div>

      <div class="post-info">
        <ol>
          <li class="post-time">2014-02-15</li> 
          <li class="post-category"> 
           工具
          </li>
        </ol>
      </div>

      <div class="post-preview">
        <h1>使用 GitHub, Jekyll 打造自己的独立博客</h1>

<p><a href="https://github.com/">GitHub</a>是一个代码托管网站，现在很多开源项目都放在GitHub上。
利用GitHub，可以让全球各地的程序员们一起协作开发。GitHub 提供了一种功能，叫
<a href="https://help.github.com/categories/20/articles">GitHub Pages</a>, 利用这个功能，我
们可以为项目建立网站，当然，这也意味着我们可以通过 GitHub Pages 建立自己的网站。</p>

<p><a href="http://jekyllrb.com/">Jekyll</a>是一个简单的，针对博客设计的静态网站生成器。使用
GitHub 和 Jekyll，我们可以打造自己的独立博客，你可以自由地定制网站的风格，并且这
一切都是免费的。</p>

<p>这是我在GitHub上自己建立的<a href="http://minixalpha.github.io/">博客</a>
及<a href="https://github.com/minixalpha/minixalpha.github.io">源代码</a>
（两个分支），在下文的讲解中，你可以随时查看博客的源代码，以便有直观的认识。</p>

<p>网站截图：</p>

<p><img src="/assets/blog-images/blog_snapshot.png" alt="blog_snapshot"></p>
 
        <a href="/%E5%B7%A5%E5%85%B7/2014/02/15/github-jekyll-markdown.html"> Read More ... </a> </br>
      </div>

    </li>
    
    <li>
      <div class="post-title">
        <a href="/%E6%8A%80%E6%9C%AF/2014/01/26/wsgi-intro.html"> WSGI 简介</a> </br>
      </div>

      <div class="post-info">
        <ol>
          <li class="post-time">2014-01-26</li> 
          <li class="post-category"> 
           技术
          </li>
        </ol>
      </div>

      <div class="post-preview">
        <h1>WSGI 简介</h1>

<h2>背景</h2>

<p>Python Web 开发中，服务端程序可以分为两个部分，一是服务器程序，二是应用程序。前者负责把客户端请求接收，整理，后者负责具体的逻辑处理。为了方便应用程序的开发，我们把常用的功能封装起来，成为各种Web开发框架，例如 Django, Flask, Tornado。不同的框架有不同的开发方式，但是无论如何，开发出的应用程序都要和服务器程序配合，才能为用户提供服务。这样，服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架，都是不好的。对服务器来说，需要支持各种不同框架，对框架来说，只有支持它的服务器才能被开发出的应用使用。</p>

<p>这时候，标准化就变得尤为重要。我们可以设立一个标准，只要服务器程序支持这个标准，框架也支持这个标准，那么他们就可以配合使用。一旦标准确定，双方各自实现。这样，服务器可以支持更多支持标准的框架，框架也可以使用更多支持标准的服务器。</p>

<p>Python Web开发中，这个标准就是 <em>The Web Server Gateway Interface</em>, 即 <strong>WSGI</strong>. 这个标准在<a href="http://www.python.org/dev/peps/pep-0333/">PEP 333</a>中描述，后来，为了支持 Python 3.x, 并且修正一些问题，新的版本在<a href="http://www.python.org/dev/peps/pep-3333/">PEP 3333</a>中描述。</p>

<h2>WSGI 是什么</h2>

<p>WSGI 是服务器程序与应用程序的一个约定，它规定了双方各自需要实现什么接口，提供什么功能，以便二者能够配合使用。</p>

<p>WSGI 不能规定的太复杂，否则对已有的服务器来说，实现起来会困难，不利于WSGI的普及。同时WSGI也不能规定的太多，例如cookie处理就没有在WSGI中规定，这是为了给框架最大的灵活性。要知道WSGI最终的目的是为了方便服务器与应用程序配合使用，而不是成为一个Web框架的标准。</p>

<p>另一方面，WSGI需要使得middleware（是中间件么？）易于实现。middleware处于服务器程序与应用程序之间，对服务器程序来说，它相当于应用程序，对应用程序来说，它相当于服务器程序。这样，对用户请求的处理，可以变成多个 middleware 叠加在一起，每个middleware实现不同的功能。请求从服务器来的时候，依次通过middleware，响应从应用程序返回的时候，反向通过层层middleware。我们可以方便地添加，替换middleware，以便对用户请求作出不同的处理。</p>
 
        <a href="/%E6%8A%80%E6%9C%AF/2014/01/26/wsgi-intro.html"> Read More ... </a> </br>
      </div>

    </li>
    
    <li>
      <div class="post-title">
        <a href="/%E6%BA%90%E4%BB%A3%E7%A0%81%E9%98%85%E8%AF%BB/2014/01/24/wsgiref-src-intro.html"> wsgiref 源代码分析</a> </br>
      </div>

      <div class="post-info">
        <ol>
          <li class="post-time">2014-01-24</li> 
          <li class="post-category"> 
           源代码阅读
          </li>
        </ol>
      </div>

      <div class="post-preview">
        <h1>wsgiref 源代码分析</h1>

<h2>wsgiref</h2>

<p><a href="http://docs.python.org/2/library/wsgiref.html">wsgiref</a> 是Python标准库给出的 <a href="http://www.python.org/dev/peps/pep-0333/">WSGI</a> 的参考实现。</p>

<p>WSGI是Python Web 开发中为服务器程序和应用程序设定的标准，满足这一标准的服务器程序和应用程序可以配合使用。我在上一篇博文《<a href="http://blog.csdn.net/on_1y/article/details/18803563">WSGI简介</a>》中对此有详细的介绍。在阅读wsgiref源代码之前，一定要对WSGI有一定了解。</p>

<p>WSGI 在 <a href="http://www.python.org/dev/peps/pep-0333/">PEP 333</a> 中描述，但是只靠阅读PEP 333 可能在理解上还是不够深入，所以阅读官方给出的参考实现是很有必要的。阅读完这份源代码后，不仅有利于对WSGI的理解。而且会让你对服务端程序如何对客户端请求有一个直观的理解，从相对底层的socket监听请求，到上层对HTTP请求的处理。</p>

<p>当然，这只是对WSGI的参考实现，目的是为了描述清楚WSGI，而不是真正用在产品中。如果想对Python Web开发中服务器端的实现有更广泛，更深入的理解，需要进一步阅读Python常用框架的源代码。</p>

<h2>wsgiref 源代码分析</h2>

<p>wsgiref 源代码可以在 <a href="https://pypi.python.org/pypi/wsgiref">pypi wsgiref 0.1.2</a> 下载。另外，我在阅读的过程中作了大量注释，包含模块介绍，调用层次关系，demo的运行结果，等 等，还包含了阅读过程中制作的思维导图。GitHub地址<a href="https://github.com/minixalpha/SourceLearning/tree/master/wsgiref-0.1.2">注释版wsgiref</a>。</p>

<h3>结构</h3>

<p><img src="/assets/blog-images/wsgiref.bmp" alt="wsgiref"></p>

<p>上图描述了wsgiref的所有模块及模块间的调用关系，可以看出，wsgiref有以下模块：</p>

<ul>
<li><p>simple_server<br>
这一模块实现了一个简单的 HTTP 服务器，并给出了一个简单的 demo，运行：</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">python simple_server.py
</code></pre></div></li>
</ul>

<p>会启动这个demo，运行一次请求，并把这次请求中涉及到的环境变量在浏览器中显示出来。</p>

<ul>
<li>handlers<br>
simple_server模块将HTTP服务器分成了 Server 部分和Handler部分，前者负责接收请求，后者负责具体的处理，
其中Handler部分主要在handlers中实现。</li>
<li>headers<br>
这一模块主要是为HTTP协议中header部分建立数据结构。</li>
<li>util<br>
这一模块包含了一些工具函数，主要用于对环境变量，URL的处理。</li>
<li>validate<br>
这一模块提供了一个验证工具，可以用于验证你的实现是否符合WSGI标准。</li>
</ul>

<h3>simple_server</h3>
 
        <a href="/%E6%BA%90%E4%BB%A3%E7%A0%81%E9%98%85%E8%AF%BB/2014/01/24/wsgiref-src-intro.html"> Read More ... </a> </br>
      </div>

    </li>
    
    <li>
      <div class="post-title">
        <a href="/%E6%80%9D%E6%83%B3/2014/01/13/write_high_quality_program.html"> 如何编写高质量的程序</a> </br>
      </div>

      <div class="post-info">
        <ol>
          <li class="post-time">2014-01-13</li> 
          <li class="post-category"> 
           思想
          </li>
        </ol>
      </div>

      <div class="post-preview">
        <h1>如何编写高质量的程序</h1>

<p>学习任何编程语言都会有一个基本的过程，开始的时候学习基本的语法，然后学习各种库，框架，开始做各种项目。在做项目的过程中，随着代码量的增加，我们会渐渐感到失去对程序的掌控能力，bug开始增加，牵一发而动全身，顾此失彼。这充分说明了编写高质量程序的重要性，这里的“高质量”主要指程序的正确性，可读性，可维护性。</p>

<h2>什么是高质量的程序</h2>

<h3>正确性</h3>

<p>程序正确性的重要程度无需多言，尤其在一些特殊领域，例如芯片制造业，航天业，武器制造业，对程序正确性往往有着极其严格的要求，因为一旦程序出错，代价往往是巨大的。在这些领域，需要使用形式化方法(formal methods)来自动验证程序的正确性，也就是说你需要证明程序的正确性，而不仅仅保证程序在大多数情况下是正确的。在其它领域，对正确性没有这么高要求，形式化方法也不适用，但是我们还是需要使用其它手段，例如测试，code review等等来保证软件的正确性。</p>

<h3>可读性</h3>

<p>可读性可以帮助程序作者理清思路，思路清晰后，程序不容易出错。另外，其它程序员在维护你的代码时，更容易理解你的意思，方便修改bug，方便扩展。</p>

<p>不要浪费自己的时间，更不要浪费别人的时间。</p>

<h3>可维护性</h3>

<p>这里的可维护性主要指程序应对变化的能力。程序在完成基本功能后，可能会发生各种改变：用户需求变了，性能达不到要求需要重新实现算法，等等。一旦程序的一个点发生改变，其它点如果也需要同时手动改变，那么程序会变的不可控制，出bug的机会会增加。想像一下，我们的程序是一个盒子，在添加新功能时，如果只需要把新模块插到一个地方，新模块就可以被系统使用，这样的程序可维护性是很高的。但是如果添加新功能时，需要把原来的程序盒子拆开，其它模块也需要相应修改，才能加入新模块，这样的程序可维护性就很差。</p>
 
        <a href="/%E6%80%9D%E6%83%B3/2014/01/13/write_high_quality_program.html"> Read More ... </a> </br>
      </div>

    </li>
    
    <li>
      <div class="post-title">
        <a href="/%E6%BA%90%E4%BB%A3%E7%A0%81%E9%98%85%E8%AF%BB/2013/11/21/gmodules_arch.html"> web.py 项目架构分析之 googlemodules</a> </br>
      </div>

      <div class="post-info">
        <ol>
          <li class="post-time">2013-11-21</li> 
          <li class="post-category"> 
           源代码阅读
          </li>
        </ol>
      </div>

      <div class="post-preview">
        <h1>web.py 项目之 googlemodules</h1>

<h2>项目说明</h2>

<p>项目来自 <a href="http://webpy.org/src/">webpy.org</a>, 这是一个真实的在线上运行的
项目: <a href="http://www.googlemodules.com/">Google Modules</a>, 可以上传，下载，
一些模块，还有一些评分，打标签等等功能。(不过这网站挺奇怪的。。。)</p>

<h2>目录树</h2>
<div class="highlight"><pre><code class="text language-text" data-lang="text">src/
    ├── application.py
    ├── forum.py
    ├── config_example.py
    ├── INSTALL
    ├── LICENCE
    ├── app
    │   ├── controllers
    │   ├── helpers
    │   ├── models
    │   └── views
    ├── app_forum
    │   ├── controllers
    │   ├── models
    │   └── views
    ├── data
    ├── public
    │   ├── css
    │   ├── img
    │   │   └── star
    │   ├── js
    │   └── rss
    ├── scripts
    └── sql

18 directories
</code></pre></div>
<p>终于遇到个稍微大一点的项目了，要好好看看。</p>

<p>从目录上看，整个项目分成两个部分，app 和 app_forum,每个部分都使用了
典型的MVC结构，将app分成 controllers, models, views 三大部分。</p>

<p>另外，网站使用的 css, js 文件，图片，也都统一放在了public目录下。</p>

<p>INSTALL 文件描述了如何安装部署项目, 包括在哪里下载项目，哪里下载web.py，如何
配置 lighttpd, 如何配置项目。</p>

<p>config_example.py 文件给了一个配置文件模板，按自己的需要修改其中内容，最后
把文件名改为 config.py 就可以了，其中包括对数据的配置，调试，缓存的开启等等。</p>

<p>LICENCE 文件描述了项目使用的开源协议: GPLv3。</p>

<p>项目使用的脚本放在scripts目录下，创建数据库使用的文件放在了sql目录下。</p>

<h2>代码统计</h2>

<p>先看看代码统计</p>

<p><img src="/assets/blog-images/googlemodules_code_stat.jpg" alt="googlemodules_code_stat.jpg"></p>

<h2>application 模块</h2>

<h3>application.py</h3>
<div class="highlight"><pre><code class="python language-python" data-lang="python"><span class="c">#!/usr/bin/env python</span>
<span class="c"># Author: Alex Ksikes </span>

<span class="c"># TODO: </span>
<span class="c"># - setup SPF for sendmail and </span>
<span class="c"># - emailerrors should be sent from same domain</span>
<span class="c"># - clean up schema.sql</span>
<span class="c"># - because of a bug in webpy unicode search fails (see models/sql_search.py)</span>

<span class="kn">import</span> <span class="nn">web</span>
<span class="kn">import</span> <span class="nn">config</span>
<span class="kn">import</span> <span class="nn">app.controllers</span>

<span class="kn">from</span> <span class="nn">app.helpers</span> <span class="kn">import</span> <span class="n">custom_error</span>

<span class="kn">import</span> <span class="nn">forum</span>

<span class="n">urls</span> <span class="o">=</span> <span class="p">(</span>        
    <span class="c"># front page</span>
    <span class="s">&#39;/&#39;</span><span class="p">,</span>                                    <span class="s">&#39;app.controllers.base.index&#39;</span><span class="p">,</span>
    <span class="s">&#39;/page/([0-9]+)/&#39;</span><span class="p">,</span>                      <span class="s">&#39;app.controllers.base.list&#39;</span><span class="p">,</span>

    <span class="c"># view, add a comment, vote</span>
    <span class="s">&#39;/module/([0-9]+)/&#39;</span><span class="p">,</span>                    <span class="s">&#39;app.controllers.module.show&#39;</span><span class="p">,</span>
    <span class="s">&#39;/module/([0-9]+)/comment/&#39;</span><span class="p">,</span>            <span class="s">&#39;app.controllers.module.comment&#39;</span><span class="p">,</span>
    <span class="s">&#39;/module/([0-9]+)/vote/&#39;</span><span class="p">,</span>               <span class="s">&#39;app.controllers.module.vote&#39;</span><span class="p">,</span>

    <span class="c"># submit a module</span>
    <span class="s">&#39;/submit/&#39;</span><span class="p">,</span>                             <span class="s">&#39;app.controllers.submit.submit&#39;</span><span class="p">,</span>

    <span class="c"># view author page</span>
    <span class="s">&#39;/author/(.*?)/&#39;</span><span class="p">,</span>                       <span class="s">&#39;app.controllers.author.show&#39;</span><span class="p">,</span>      

    <span class="c"># search browse by tag name</span>
    <span class="s">&#39;/search/&#39;</span><span class="p">,</span>                             <span class="s">&#39;app.controllers.search.search&#39;</span><span class="p">,</span>    
    <span class="s">&#39;/tag/(.*?)/&#39;</span><span class="p">,</span>                          <span class="s">&#39;app.controllers.search.list_by_tag&#39;</span><span class="p">,</span>

    <span class="c"># view tag clouds</span>
    <span class="s">&#39;/tags/&#39;</span><span class="p">,</span>                               <span class="s">&#39;app.controllers.cloud.tag_cloud&#39;</span><span class="p">,</span>
    <span class="s">&#39;/authors/&#39;</span><span class="p">,</span>                            <span class="s">&#39;app.controllers.cloud.author_cloud&#39;</span><span class="p">,</span>

    <span class="c"># table modules</span>
    <span class="s">&#39;/modules/(?:by-(.*?)/)?([0-9]+)?/?&#39;</span><span class="p">,</span>   <span class="s">&#39;app.controllers.all_modules.list_by&#39;</span><span class="p">,</span>

    <span class="c"># static pages</span>
    <span class="s">&#39;/feedback/&#39;</span><span class="p">,</span>                           <span class="s">&#39;app.controllers.feedback.send&#39;</span><span class="p">,</span>
    <span class="s">&#39;/about/&#39;</span><span class="p">,</span>                              <span class="s">&#39;app.controllers.base.about&#39;</span><span class="p">,</span>
    <span class="s">&#39;/help/&#39;</span><span class="p">,</span>                               <span class="s">&#39;app.controllers.base.help&#39;</span><span class="p">,</span>

    <span class="c"># let lighttpd handle in production</span>
    <span class="s">&#39;/(?:css|img|js|rss)/.+&#39;</span><span class="p">,</span>               <span class="s">&#39;app.controllers.public.public&#39;</span><span class="p">,</span>

    <span class="c"># canonicalize /urls to /urls/</span>
    <span class="s">&#39;/(.*[^/])&#39;</span><span class="p">,</span>                            <span class="s">&#39;app.controllers.public.redirect&#39;</span><span class="p">,</span>

    <span class="c"># mini forum app</span>
    <span class="s">&#39;/forum&#39;</span><span class="p">,</span>                               <span class="n">forum</span><span class="o">.</span><span class="n">app</span><span class="p">,</span>    

    <span class="s">&#39;/hello/(.*)&#39;</span><span class="p">,</span>                            <span class="s">&#39;hello&#39;</span><span class="p">,</span>

    <span class="c"># site admin app</span>
<span class="c">#    &#39;/admin&#39;,                              admin.app,    </span>
<span class="p">)</span>

<span class="n">app</span> <span class="o">=</span> <span class="n">web</span><span class="o">.</span><span class="n">application</span><span class="p">(</span><span class="n">urls</span><span class="p">,</span> <span class="nb">globals</span><span class="p">())</span>
<span class="n">custom_error</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</code></pre></div>
<p>可以看出，这是 application 部分的入口，这个模块仅仅是定义了各个请求的处理方式，
并完成程序的启动，所有的实现均不在这里出现，而是通过 <code>import</code> 导入，特别需要
注意 <code>urls</code> 最后定义的 <code>/forum</code> 和 <code>/admin</code> 使用了子程序，而不是通过之前的字符串
实现映射。还需要注意对静态文件,即css,js,img,rss文件的单独处理。</p>

<p>所有这些都与之前分析过的那些小项目不同，回想起我之前写的 
<a href="https://github.com/minixalpha/BlogSystem">BlogSystem</a>, 所有的处理实现都放在
同一个文件中，导致最后一个文件居然 700多行，真是让人潸然泪下。。。
而且之前也不知道使用子程序，所有处理都堆在一起。看来读完这份源代码，真应该重构一
下了。</p>

<h3>app 模块</h3>
<div class="highlight"><pre><code class="text language-text" data-lang="text">app/
    ├── models # 数据模块，MVC中的 M
    ├── views # 显示模块，MVC中的 V
    ├── controllers # 控制模块，MVC中的 C
    └── helpers # 辅助模块，实现辅助功能

4 directories
</code></pre></div>
<h3>controllers 模块</h3>
<div class="highlight"><pre><code class="text language-text" data-lang="text">controllers/
    ├── base.py         # 对基本页面，如网站主页,关于网页，帮助等的处理
    ├── all_modules.py  # 显示全部模块
    ├── module.py       # 对模块页面的处理
    ├── search.py       # 对搜索模块功能处理
    ├── submit.py       # 对提交模块的处理
    ├── author.py       # 查看模块作者信息
    ├── cloud.py        # 对标签云页面进行处理
    ├── feedback.py     # 处理反馈信息
    └── public.py       # 对静态文件的处理
</code></pre></div>
<p>这个模块主要是对请求处理的实现，在 <code>urls</code> 里定义的那些映射关系，
很多被映射到这里。</p>

<p>实现过程中，调用 models 模块对数据操作，再送入 views 模块通过模板引擎显示数据内容。</p>

<h3>models 模块</h3>
<div class="highlight"><pre><code class="text language-text" data-lang="text">models/
    ├── comments.py     # 对评论数据的处理
    ├── modules.py      # 对模块数据的处理
    ├── rss.py          # 对 rss 订阅的处理
    ├── sql_search.py   # 对搜索的数据处理
    ├── submission.py   # 对用户提交内容的处理
    ├── tags.py         # 对标签内容的数据处理
    └── votes.py        # 对用户投票的数据处理
</code></pre></div>
<p>这个模块直接调用 web.py 的db模块对数据库进行操作，对数据库的连接在 config.py 中
已经完成。这里完成数据的获取，处理，返回。可以看出，对不同种类的数据又分成了
很多小的模块。</p>
 
        <a href="/%E6%BA%90%E4%BB%A3%E7%A0%81%E9%98%85%E8%AF%BB/2013/11/21/gmodules_arch.html"> Read More ... </a> </br>
      </div>

    </li>
    
</ul>

<!-- Pagination links -->

<div class="pagination">
  
    <a href="/page4">&laquo; Prev</a>
  

  
    
      <a href="/index.html">1</a>
    
  
    
      <a href="/page2">2</a>
    
  
    
      <a href="/page3">3</a>
    
  
    
      <a href="/page4">4</a>
    
  
    
      5
    
  
    
      <a href="/page6">6</a>
    
  
    
      <a href="/page7">7</a>
    
  
    
      <a href="/page8">8</a>
    
  

  
    <a href="/page6">Next &raquo;</a>
  
</div>



      </article>

      <div class="comments">
        
      </div>


      <footer>
        Copyright (c) minixalpha 2014
      </footer>

    </div>
  </body>
</html>
